﻿using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;
using System.Windows;
using MvCamCtrl.NET;
using AIVision.Repository.Entitys;
using System.IO;

namespace AIVision.Inspect.Toolkit
{
    public partial class HKCamerSDK : MyBaseCamera
    {
        //创建相机集合，用于存放相机
        MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList;
        MyCamera.MV_CC_DEVICE_INFO device;
        MyCamera HKMyCamera = new MyCamera();
        MyCamera.cbOutputExdelegate ImageCallback;
        MyCamera.cbExceptiondelegate pCallBackFunc;
        HObject hPylonImage = new HObject();

        /// <summary>
        /// 查找并开启相机
        /// </summary>
        /// <param name="CamerNum">开启第几个相机</param>
        /// <returns>开启成功返回true，开启失败返回false，并在输出打印错误码</returns>
        public override List<string> FindCamer()
        {
            int nRet;
            List<string> CamerName = new List<string>();
            // ch:创建设备列表 en:Create Device List
            GC.Collect();

            nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
            if (0 != nRet)
            {
                Console.WriteLine("NOT find Camer! {0:x8}", nRet);
                return null;
            }

            //在输出打印相机名称 
            for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
            {
                MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
                //网口相机
                if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
                {
                    IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
                    MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
                    if (gigeInfo.chUserDefinedName != "")
                    {
                        Console.WriteLine("GigE: " + gigeInfo.chUserDefinedName + " (" + gigeInfo.chSerialNumber + ")");
                        CamerName.Add(gigeInfo.chSerialNumber);
                    }
                    else
                    {
                        Console.WriteLine("GigE: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")");
                    }
                }
                //usb接口相机
                else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
                {
                    IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stUsb3VInfo, 0);
                    MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO));
                    if (usbInfo.chUserDefinedName != "")
                    {
                        Console.WriteLine("USB: " + usbInfo.chUserDefinedName + " (" + usbInfo.chSerialNumber + ")");
                    }
                    else
                    {
                        Console.WriteLine("USB: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")");
                    }
                }
            }
            if (m_pDeviceList.nDeviceNum == 0)
            {
                Console.WriteLine("未找到USB或者网口相机", 0);
                return null;
            }
            return CamerName;

        }
        /// <summary>
        /// 根据相机序列号开启相机-拍照回调模式
        /// </summary>
        /// <param name="CamerSerialization"></param>
        /// <returns></returns>
        public override bool OpenCamerForCallBack(string CamerSerialization)
        {
            int nRet = 0;

            for (int i = 0; i < m_pDeviceList.pDeviceInfo.Length; i++)
            {
                MyCamera.MV_CC_DEVICE_INFO tmpDriver = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));

                byte[] GUIDArray = new byte[12];
                Array.Copy(tmpDriver.SpecialInfo.stCamLInfo, 12, GUIDArray, 0, 12);
                var GUID = Encoding.ASCII.GetString(GUIDArray);
                var MAC = tmpDriver.nMacAddrHigh.ToString("X") + tmpDriver.nMacAddrLow.ToString("X");

                if (MAC == CamerSerialization || GUID == CamerSerialization)
                {
                    HKMyCamera = new MyCamera();
                    nRet = HKMyCamera.MV_CC_CreateDevice_NET(ref tmpDriver);
                    if (MyCamera.MV_OK != nRet)
                        throw new Exception(string.Format("连接相机错误,相机编号:{0}", CamerSerialization));
                    nRet = HKMyCamera.MV_CC_OpenDevice_NET();
                    if (MyCamera.MV_OK != nRet)
                        throw new Exception(string.Format("打开相机失败,相机编号:{0}", CamerSerialization));


                    break;
                }



            //    var v = m_pDeviceList.pDeviceInfo;
            //    device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
            //    IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
            //    MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
            //    if (gigeInfo.chSerialNumber == CamerSerialization)
            //    {
            //        break;
            //    }
            //}
            //// ch:打开设备 | en:Open device
            //if (null == HKMyCamera)
            //{
            //    HKMyCamera = new MyCamera();
            //    if (null == HKMyCamera)
            //    {
            //        return false;
            //    }
            //}
            ////循环执行1000次，用于连接相机
            //for (int i = 0; i < 10; i++)
            //{
            //    nRet = HKMyCamera.MV_CC_CreateDevice_NET(ref device);
            //    if (MyCamera.MV_OK != nRet)
            //    {
            //        Thread.Sleep(1);
            //        //输出错误信息
            //        if (i == 9) Console.WriteLine("创建相机失败! {0:x8}", nRet);
            //        continue;
            //    }

            //    nRet = HKMyCamera.MV_CC_OpenDevice_NET();
            //    if (MyCamera.MV_OK != nRet)
            //    {
            //        HKMyCamera.MV_CC_DestroyDevice_NET();
            //        Thread.Sleep(10);
            //        if (i == 9) Console.WriteLine("打开相机失败! {0:x8}", nRet);
            //    }
            //    else
            //    {
            //        break;
            //    }
            }


            // ch:探测网络最佳包大小(只对GigE相机有效) 
            if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
            {
                int nPacketSize = HKMyCamera.MV_CC_GetOptimalPacketSize_NET();
                if (nPacketSize > 0)
                {
                    nRet = HKMyCamera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
                    if (nRet != MyCamera.MV_OK)
                    {
                        Console.WriteLine("Warning: Set Packet Size failed {0:x8}", nRet);
                    }
                }
                else
                {
                    Console.WriteLine("Warning: Get Packet Size failed {0:x8}", nPacketSize);
                }
            }
            //注册图像回调函数
            ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc);
            nRet = HKMyCamera.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);
            if (MyCamera.MV_OK != nRet)
            {
                Console.WriteLine("Register image callback failed!");
                return false;
            }


            //设置开启触发模式
            HKMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
            //设置开启软触发模式
            HKMyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);

            //使用软触发命令
            nRet = HKMyCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");

            if (MyCamera.MV_OK != nRet)
            {
                m_bGrabbing = false;
                //    ShowErrorMsg("Start Grabbing Fail!", nRet);
                return false;
            }
            // ch:开始采集 
            nRet = HKMyCamera.MV_CC_StartGrabbing_NET();
            if (MyCamera.MV_OK != nRet)
            {
                Console.WriteLine("开启相机采集失败!  {0:x8}", nRet);
                return false;
            }
            return true;

        }
        /// <summary>
        /// 根据相机序列号开启相机-普通模式
        /// </summary>
        /// <param name="CamerSerialization"></param>
        /// <returns></returns>
        public override bool OpenCamer(string CamerSerialization)
        {
            int nRet = 0;

            for (int i = 0; i < m_pDeviceList.pDeviceInfo.Length; i++)
            {
                MyCamera.MV_CC_DEVICE_INFO tmpDriver = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));

                byte[] GUIDArray = new byte[12];
                Array.Copy(tmpDriver.SpecialInfo.stCamLInfo, 12, GUIDArray, 0, 12);
                var GUID = Encoding.ASCII.GetString(GUIDArray);
                var MAC = tmpDriver.nMacAddrHigh.ToString("X") + tmpDriver.nMacAddrLow.ToString("X");

                if (MAC == CamerSerialization || GUID == CamerSerialization)
                {
                    HKMyCamera = new MyCamera();
                    nRet = HKMyCamera.MV_CC_CreateDevice_NET(ref tmpDriver);
                    if (MyCamera.MV_OK != nRet)
                        throw new Exception(string.Format("连接相机错误,相机编号:{0}", CamerSerialization));
                    nRet = HKMyCamera.MV_CC_OpenDevice_NET();
                    if (MyCamera.MV_OK != nRet)
                        throw new Exception(string.Format("打开相机失败,相机编号:{0}", CamerSerialization));
                    break;
                }
            }


            // ch:探测网络最佳包大小(只对GigE相机有效) 
            if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
            {
                int nPacketSize = HKMyCamera.MV_CC_GetOptimalPacketSize_NET();
                if (nPacketSize > 0)
                {
                    nRet = HKMyCamera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
                    if (nRet != MyCamera.MV_OK)
                    {
                        Console.WriteLine("Warning: Set Packet Size failed {0:x8}", nRet);
                    }
                }
                else
                {
                    Console.WriteLine("Warning: Get Packet Size failed {0:x8}", nPacketSize);
                }
            }
            //设置开启触发模式
            HKMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
            //设置开启软触发模式
            HKMyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
            // ch:开始采集 
            nRet = HKMyCamera.MV_CC_StartGrabbing_NET();
            if (MyCamera.MV_OK != nRet)
            {
                Console.WriteLine("开启相机采集失败!  {0:x8}", nRet);
                return false;
            }
            return true;

        }
        /// <summary>
        /// 相机重连开启
        /// </summary>
        /// <param name="nMsgType"></param>
        /// <param name="pUser"></param>
        public override bool ReconnectCamer(string CamerName)
        {
            CloseCamer();

            for (int j = 0; j < m_pDeviceList.pDeviceInfo.Length; j++)
            {
                device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[j], typeof(MyCamera.MV_CC_DEVICE_INFO));
                IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
                MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
                if (gigeInfo.chSerialNumber == CamerName)
                {
                    break;
                }
            }
            int i = 0;
            // ch:打开设备 | en:Open Device
            while (true)
            {
                int nRet = HKMyCamera.MV_CC_CreateDevice_NET(ref device);
                i++;
                //防止重连超时卡死
                if (i > 10000)
                {
                    Console.WriteLine("相机重连超时，请检查相机安装");
                    nRet = -1;
                    break;
                }

                if (MyCamera.MV_OK != nRet)
                {
                    Thread.Sleep(5);
                    continue;
                }

                nRet = HKMyCamera.MV_CC_OpenDevice_NET();
                if (MyCamera.MV_OK != nRet)
                {
                    Thread.Sleep(5);
                    HKMyCamera.MV_CC_DestroyDevice_NET();
                    continue;
                }
                else
                {
                    //nRet = InitCamera();
                    if (MyCamera.MV_OK != nRet)
                    {
                        Thread.Sleep(5);
                        HKMyCamera.MV_CC_DestroyDevice_NET();
                        continue;
                    }
                    break;
                }

            }
            return true;

        }
        /// <summary>
        /// 清空相机
        /// </summary>
        public override bool CloseCamer()
        {
            // ch:停止采集 | en:Stop Grabbing
            HKMyCamera.MV_CC_StopGrabbing_NET();
            // ch:关闭设备 | en:Close Device
            HKMyCamera.MV_CC_CloseDevice_NET();
            HKMyCamera.MV_CC_DestroyDevice_NET();
            return true;
        }
        //回调图像传出变量
        void ImageCallbackFunc(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
        {
            Halcon_Image(pData, ref pFrameInfo, pUser);
        }
        public void Halcon_Image(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
        {
            int nRet;
            HObject img = new HObject();
            IntPtr pImageBuf = IntPtr.Zero;
            int nImageBufSize = 0;
            IntPtr pTemp = IntPtr.Zero;
            if (IsColorPixelFormat(pFrameInfo.enPixelType))
            {
                if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
                {
                    pTemp = pData;
                }
                else
                {
                    if (IntPtr.Zero == pImageBuf || nImageBufSize < pFrameInfo.nWidth * pFrameInfo.nHeight * 3)
                    {
                        if (pImageBuf != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(pImageBuf);
                            pImageBuf = IntPtr.Zero;
                        }

                        pImageBuf = Marshal.AllocHGlobal(pFrameInfo.nWidth * pFrameInfo.nHeight * 3);
                        if (IntPtr.Zero == pImageBuf)
                        {
                            Console.WriteLine("图像采集为空");
                            return;
                        }
                        nImageBufSize = pFrameInfo.nWidth * pFrameInfo.nHeight * 3;
                    }

                    MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

                    stPixelConvertParam.pSrcData = pData;//源数据
                    stPixelConvertParam.nWidth = pFrameInfo.nWidth;//图像宽度
                    stPixelConvertParam.nHeight = pFrameInfo.nHeight;//图像高度
                    stPixelConvertParam.enSrcPixelType = pFrameInfo.enPixelType;//源数据的格式
                    stPixelConvertParam.nSrcDataLen = pFrameInfo.nFrameLen;

                    stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
                    stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
                    stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;


                    nRet = HKMyCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
                    if (MyCamera.MV_OK != nRet)
                    {
                        Console.WriteLine("图像转换异常");
                        return;
                    }
                    pTemp = stPixelConvertParam.pDstBuffer;
                }

                try
                {
                    HOperatorSet.GenImageInterleaved(out hPylonImage, (HTuple)pTemp, (HTuple)"rgb", (HTuple)pFrameInfo.nWidth, (HTuple)pFrameInfo.nHeight, -1, "byte", 0, 0, 0, 0, -1, 0);

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    return;
                }
            }
            else if (IsMonoPixelFormat(pFrameInfo.enPixelType))
            {
                if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
                {
                    pTemp = pData;
                }
                else
                {
                    if (IntPtr.Zero == pImageBuf || nImageBufSize < pFrameInfo.nWidth * pFrameInfo.nHeight)
                    {
                        if (pImageBuf != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(pImageBuf);
                            pImageBuf = IntPtr.Zero;
                        }

                        pImageBuf = Marshal.AllocHGlobal(pFrameInfo.nWidth * pFrameInfo.nHeight);
                        if (IntPtr.Zero == pImageBuf)
                        {
                            Console.WriteLine("图像采集为空");
                            return;
                        }
                        nImageBufSize = pFrameInfo.nWidth * pFrameInfo.nHeight;
                    }

                    MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

                    stPixelConvertParam.pSrcData = pData;//源数据
                    stPixelConvertParam.nWidth = pFrameInfo.nWidth;//图像宽度
                    stPixelConvertParam.nHeight = pFrameInfo.nHeight;//图像高度
                    stPixelConvertParam.enSrcPixelType = pFrameInfo.enPixelType;//源数据的格式
                    stPixelConvertParam.nSrcDataLen = pFrameInfo.nFrameLen;

                    stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
                    stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
                    stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
                    nRet = HKMyCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
                    if (MyCamera.MV_OK != nRet)
                    {
                        Console.WriteLine("图像转换异常");
                        return;
                    }
                    pTemp = stPixelConvertParam.pDstBuffer; ;
                }
                try
                {
                    HOperatorSet.GenImage1Extern(out hPylonImage, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, pTemp, IntPtr.Zero);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    return;
                }
            }
            else
            {
                Console.WriteLine("采集图像格式错误，不为彩色和黑白图像");
                return;
            }

            try
            {
                GetImage(hPylonImage);//调用相机基类的函数，用于传出变量
                hPylonImage.Dispose();
                m_bGrabbing = false;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return;
            }
        }
        /// <summary>
        /// 设置相机曝光
        /// </summary>
        /// <param name="ExposureTime"></param>
        /// <returns></returns>
        public override bool SetExposureTime(int ExposureTime)
        {
            try
            {
                HKMyCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
                int nRet = HKMyCamera.MV_CC_SetFloatValue_NET("ExposureTime", ExposureTime);
                if (nRet != MyCamera.MV_OK)
                {
                    return false;
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }
        /// <summary>
        /// 设置Gige相机心跳时间
        /// </summary>
        /// <param name="value"></param>
        public void SetHeartBeatTime(uint value)
        {
            try
            {
                //判断是否是网口相机
                if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
                {
                    HKMyCamera.MV_CC_SetHeartBeatTimeout_NET(value);
                }

            }
            catch (Exception)
            {

            }
        }

        bool m_bGrabbing = false;
        /// <summary>
        /// 单张采集-回调
        /// </summary>
        public override bool OneGrapForCallBack()
        {
            try
            {
                if (m_bGrabbing)
                {
                    Console.WriteLine("Camera is now Continue Grabing Images！");

                    return false;
                }
                else
                {
                    // ch:标志位置位true | en:Set position bit true
                    m_bGrabbing = true;

                    //设置开启触发模式
                    HKMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
                    //设置开启软触发模式
                    HKMyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
                    int nRet;
                    //使用软触发命令
                    nRet = HKMyCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");

                    if (MyCamera.MV_OK != nRet)
                    {
                        m_bGrabbing = false;
                        return false;
                    }
                    // HeventSlim.Wait();
                    return true;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 单张采集
        /// </summary>
        public override HObject OneGrap()
        {
            HObject currentImg = null;
            try
            {
                if (m_bGrabbing)
                {
                    return currentImg;
                }
                else
                {
                    // ch:标志位置位true | en:Set position bit true
                    m_bGrabbing = true;

                    //设置开启触发模式
                    HKMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
                    //设置开启软触发模式
                    HKMyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
                    int nRet1;
                    //使用软触发命令
                    nRet1 = HKMyCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
                    IntPtr pImageBuf = IntPtr.Zero;
                    int nImageBufSize = 0;
                    IntPtr pTemp = IntPtr.Zero;
                    MyCamera.MV_FRAME_OUT stFrameOut = new MyCamera.MV_FRAME_OUT();
                    int nRet = HKMyCamera.MV_CC_GetImageBuffer_NET(ref stFrameOut, 1000);
                    if (MyCamera.MV_OK == nRet)
                    {
                        if (IsColorPixelFormat(stFrameOut.stFrameInfo.enPixelType))
                        {
                            if (stFrameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
                            {
                                pTemp = stFrameOut.pBufAddr;
                            }
                            else
                            {
                                if (IntPtr.Zero == pImageBuf || nImageBufSize < (stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight * 3))
                                {
                                    if (pImageBuf != IntPtr.Zero)
                                    {
                                        Marshal.FreeHGlobal(pImageBuf);
                                        pImageBuf = IntPtr.Zero;
                                    }

                                    pImageBuf = Marshal.AllocHGlobal((int)stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight * 3);
                                    nImageBufSize = stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight * 3;
                                }

                                MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

                                stPixelConvertParam.pSrcData = stFrameOut.pBufAddr;//源数据
                                stPixelConvertParam.nWidth = stFrameOut.stFrameInfo.nWidth;//图像宽度
                                stPixelConvertParam.nHeight = stFrameOut.stFrameInfo.nHeight;//图像高度
                                stPixelConvertParam.enSrcPixelType = stFrameOut.stFrameInfo.enPixelType;//源数据的格式
                                stPixelConvertParam.nSrcDataLen = stFrameOut.stFrameInfo.nFrameLen;

                                stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
                                stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
                                stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;
                                nRet = HKMyCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
                                pTemp = pImageBuf;
                            }

                            try
                            {
                                HOperatorSet.GenImageInterleaved(out currentImg, (HTuple)pTemp, (HTuple)"rgb", (HTuple)stFrameOut.stFrameInfo.nWidth, (HTuple)stFrameOut.stFrameInfo.nHeight, -1, "byte", 0, 0, 0, 0, -1, 0);
                                
                            }
                            catch (System.Exception ex)
                            {
                                throw new Exception(ex.ToString());
                            }
                        }
                        else if (IsMonoPixelFormat(stFrameOut.stFrameInfo.enPixelType))
                        {
                            if (stFrameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
                            {
                                pTemp = stFrameOut.pBufAddr;
                            }
                            else
                            {
                                if (IntPtr.Zero == pImageBuf || nImageBufSize < (stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight))
                                {
                                    if (pImageBuf != IntPtr.Zero)
                                    {
                                        Marshal.FreeHGlobal(pImageBuf);
                                        pImageBuf = IntPtr.Zero;
                                    }

                                    pImageBuf = Marshal.AllocHGlobal((int)stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight);
                                    nImageBufSize = stFrameOut.stFrameInfo.nWidth * stFrameOut.stFrameInfo.nHeight;
                                }

                                MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

                                stPixelConvertParam.pSrcData = stFrameOut.pBufAddr;//源数据
                                stPixelConvertParam.nWidth = stFrameOut.stFrameInfo.nWidth;//图像宽度
                                stPixelConvertParam.nHeight = stFrameOut.stFrameInfo.nHeight;//图像高度
                                stPixelConvertParam.enSrcPixelType = stFrameOut.stFrameInfo.enPixelType;//源数据的格式
                                stPixelConvertParam.nSrcDataLen = stFrameOut.stFrameInfo.nFrameLen;

                                stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
                                stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
                                stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
                                nRet = HKMyCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
                                pTemp = pImageBuf;
                            }
                            try
                            {
                                HOperatorSet.GenImage1Extern(out currentImg, "byte", stFrameOut.stFrameInfo.nWidth, stFrameOut.stFrameInfo.nHeight, pTemp, IntPtr.Zero);
                                var CurrentImagePath = Path.Combine("D:\\", Guid.NewGuid().ToString() + ".bmp");
                                HOperatorSet.WriteImage(currentImg, "bmp", 0, CurrentImagePath);
                                HOperatorSet.ReadImage(out currentImg, CurrentImagePath);
                                if(File.Exists(CurrentImagePath))
                                    File.Delete(CurrentImagePath);
                            }
                            catch (System.Exception ex)
                            {
                                throw new Exception(ex.ToString());
                            }
                        }
                        //else
                        //{
                        //    m_pMyCamera.MV_CC_FreeImageBuffer_NET(ref stFrameOut);
                        // }
                        //HalconDisplay(stFrameOut.stFrameInfo.nHeight, stFrameOut.stFrameInfo.nWidth);

                        HKMyCamera.MV_CC_FreeImageBuffer_NET(ref stFrameOut);
                        if (pImageBuf != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(pImageBuf);
                            pImageBuf = IntPtr.Zero;
                        }
                        m_bGrabbing=false;
                    }
                    // HeventSlim.Wait();
                    m_bGrabbing = false;
                    return currentImg;
                }
            }
            catch (Exception)
            {
                m_bGrabbing = false;
                return currentImg;
            }
        }

        /// <summary>
        /// 开启硬触发
        /// </summary>
        /// <returns></returns>
        public override bool EncoderGrap()
        {
            try
            {
                if (m_bGrabbing)
                {
                    Console.WriteLine("Camera is now Continue Grabing Images！");
                    return false;
                }
                else
                {
                    // ch:标志位置位true | en:Set position bit true
                    m_bGrabbing = true;

                    HKMyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
                    //设置使用硬触发模式
                    int nRet = HKMyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);


                    if (MyCamera.MV_OK != nRet)
                    {
                        m_bGrabbing = false;
                        return false;
                    }
                    return true;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }
        /// <summary>
        /// 判断是否为彩色图像
        /// </summary>
        /// <param name="enType"></param>
        /// <returns></returns>
        private bool IsColorPixelFormat(MyCamera.MvGvspPixelType enType)
        {
            switch (enType)
            {
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGBA8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGRA8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed:
                    return true;
                default:
                    return false;
            }
        }
        /// <summary>
        /// 判断图像是否是黑白图像
        /// </summary>
        /// <param name="enType"></param>
        /// <returns></returns>
        private bool IsMonoPixelFormat(MyCamera.MvGvspPixelType enType)
        {
            switch (enType)
            {
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
                    return true;
                default:
                    return false;
            }
        }
    }
}
